/**
 * @file platform_client.h
 * @brief IoT平台对接客户端接口
 * @details 严格按照MQTT平台与云端交互协议文档实现，包括设备上下线、主动注册、物模型获取、
 *          设备升级、属性上报/设置、事件上报、服务调用等功能
 * 
 * @author zyb
 * @date 2025-11-04
 * @version 1.0
 */

#ifndef PLATFORM_CLIENT_H
#define PLATFORM_CLIENT_H

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "mqtt_client.h"

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== 错误码定义 ==================== */

/**
 * @brief 平台操作结果类型
 */
typedef enum {
    PLATFORM_SUCCESS = 0,                   /* 操作成功 */
    PLATFORM_ERROR_INVALID_PARAM = -1,      /* 无效参数 */
    PLATFORM_ERROR_MQTT_NOT_CONNECTED = -2, /* MQTT未连接 */
    PLATFORM_ERROR_JSON_PARSE = -3,         /* JSON解析失败 */
    PLATFORM_ERROR_MEMORY = -4,             /* 内存错误 */
    PLATFORM_ERROR_TIMEOUT = -5,            /* 超时 */
    PLATFORM_ERROR_UNKNOWN = -9             /* 未知错误 */
} platform_result_t;

/* ==================== 数据结构定义 ==================== */

/**
 * @brief 设备信息
 */
typedef struct {
    char product_key[64];           /* 产品Key */
    char device_name[128];          /* 设备名称 */
    char device_secret[64];         /* 设备Secret */
    char product_secret[64];        /* 产品Secret（主动注册时使用） */
} platform_device_info_t;

/**
 * @brief 设备上下线请求
 */
typedef struct {
    char id[64];                    /* 消息ID */
    char type[32];                  /* 类型: "register" 或 "unregister" */
    platform_device_info_t device;  /* 设备信息 */
} platform_device_register_req_t;

/**
 * @brief 设备上下线回复
 */
typedef struct {
    char id[64];                    /* 消息ID，与请求一致 */
    char type[32];                  /* 类型: "register" 或 "unregister" */
    char code[16];                  /* 结果: "success" 或 "fail" */
    char reason[128];               /* 错误原因（失败时） */
    char cloud_time[32];            /* 云端时间戳 */
} platform_device_register_reply_t;

/**
 * @brief 设备主动注册请求
 */
typedef struct {
    char id[64];                    /* 消息ID */
    char type[32];                  /* 类型: "signup" */
    char product_key[64];           /* 产品Key */
    char product_secret[64];        /* 产品Secret */
    char device_name[128];          /* 设备名称 */
} platform_device_signup_req_t;

/**
 * @brief 设备主动注册回复
 */
typedef struct {
    char id[64];                    /* 消息ID，与请求一致 */
    char type[32];                  /* 类型: "signup" */
    char code[16];                  /* 结果: "success" 或 "fail" */
    char product_key[64];           /* 产品Key（成功时） */
    char device_name[128];          /* 设备名称（成功时） */
    char device_secret[64];         /* 设备Secret（成功时） */
    char msg[128];                  /* 错误信息（失败时） */
} platform_device_signup_reply_t;

/**
 * @brief 物模型请求
 */
typedef struct {
    char id[64];                    /* 消息ID */
    char type[32];                  /* 类型: "total_model" 或 "simple_model" */
    char product_key[64];           /* 产品Key，值为"all"时获取所有物模型 */
} platform_model_req_t;

/**
 * @brief 物模型回复
 */
typedef struct {
    char id[64];                    /* 消息ID，与请求一致 */
    char type[32];                  /* 类型: "total_model" 或 "simple_model" */
    char code[16];                  /* 结果: "success" 或 "fail" */
    char* model;                    /* 物模型JSON字符串（成功时） */
    size_t model_len;               /* 物模型长度 */
} platform_model_reply_t;

/**
 * @brief 设备升级信息
 */
typedef struct {
    char id[64];                    /* 消息UUID */
    char url[256];                  /* 获取文件服务器HTTP路径 */
    char token[64];                 /* 获取文件服务器HTTP校验 */
    char md5sum[64];                /* 升级文件的MD5码 */
    char file_name[64];             /* 升级文件名 */
} platform_update_info_t;

/**
 * @brief 属性值结构
 */
typedef struct {
    double value;                   /* 属性值 */
    int quality;                    /* 质量码 */
    int64_t time;                   /* 时间戳 */
} platform_property_value_t;

/**
 * @brief 属性上报回调函数类型
 */
typedef void (*platform_property_set_callback_t)(const char* identifier, const void* value, size_t value_len, void* user_data);

/**
 * @brief 事件上报回调函数类型（同步事件）
 */
typedef void (*platform_event_reply_callback_t)(const char* id, const char* identifier, const char* code, void* user_data);

/**
 * @brief 服务调用回调函数类型
 */
typedef void (*platform_service_call_callback_t)(const char* id, const char* identifier, 
                                                 const void* input_params, size_t input_params_len,
                                                 void* user_data);

/**
 * @brief 设备升级回调函数类型
 */
typedef void (*platform_update_callback_t)(const platform_update_info_t* update_info, void* user_data);

/**
 * @brief 设备注册回复回调函数类型
 */
typedef void (*platform_register_reply_callback_t)(const platform_device_register_reply_t* reply, void* user_data);

/**
 * @brief 设备注册回复回调函数类型（主动注册）
 */
typedef void (*platform_signup_reply_callback_t)(const platform_device_signup_reply_t* reply, void* user_data);

/**
 * @brief 物模型回复回调函数类型
 */
typedef void (*platform_model_reply_callback_t)(const platform_model_reply_t* reply, void* user_data);

/**
 * @brief 平台客户端配置
 */
typedef struct {
    mqtt_client_handle_t mqtt_client;       /* MQTT客户端句柄 */
    platform_device_info_t device;          /* 设备信息 */
} platform_client_config_t;

/**
 * @brief 平台客户端句柄
 */
typedef void* platform_client_handle_t;

/* ==================== 函数声明 ==================== */

/**
 * @brief 创建平台客户端
 * @param config 客户端配置
 * @return 客户端句柄，失败返回NULL
 */
platform_client_handle_t platform_client_create(const platform_client_config_t* config);

/**
 * @brief 销毁平台客户端
 * @param handle 客户端句柄
 * @return 操作结果
 */
platform_result_t platform_client_destroy(platform_client_handle_t handle);

/**
 * @brief 设备上线（register）
 * @param handle 客户端句柄
 * @param req 注册请求
 * @param callback 回复回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_device_register(platform_client_handle_t handle,
                                          const platform_device_register_req_t* req,
                                          platform_register_reply_callback_t callback,
                                          void* user_data);

/**
 * @brief 设备下线（unregister）
 * @param handle 客户端句柄
 * @param req 注销请求
 * @param callback 回复回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_device_unregister(platform_client_handle_t handle,
                                             const platform_device_register_req_t* req,
                                             platform_register_reply_callback_t callback,
                                             void* user_data);

/**
 * @brief 设备主动注册（signup）
 * @param handle 客户端句柄
 * @param req 注册请求
 * @param callback 回复回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_device_signup(platform_client_handle_t handle,
                                         const platform_device_signup_req_t* req,
                                         platform_signup_reply_callback_t callback,
                                         void* user_data);

/**
 * @brief 获取物模型
 * @param handle 客户端句柄
 * @param req 请求
 * @param callback 回复回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_get_model(platform_client_handle_t handle,
                                     const platform_model_req_t* req,
                                     platform_model_reply_callback_t callback,
                                     void* user_data);

/**
 * @brief 上报属性数据
 * @param handle 客户端句柄
 * @param report_time 上报时间（毫秒）
 * @param properties JSON格式的属性数据（键值对）
 * @return 操作结果
 */
platform_result_t platform_property_post(platform_client_handle_t handle,
                                         int64_t report_time,
                                         const char* properties_json);

/**
 * @brief 设置属性设置回调
 * @param handle 客户端句柄
 * @param callback 回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_set_property_set_callback(platform_client_handle_t handle,
                                                      platform_property_set_callback_t callback,
                                                      void* user_data);

/**
 * @brief 上报事件
 * @param handle 客户端句柄
 * @param report_time 事件上报时间（毫秒）
 * @param id 事件ID
 * @param call_type 调用方式: "sync" 或 "async"
 * @param identifier 事件标识符
 * @param output_data JSON格式的输出参数
 * @param callback 同步事件的回复回调（仅call_type为"sync"时有效）
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_event_post(platform_client_handle_t handle,
                                      int64_t report_time,
                                      const char* id,
                                      const char* call_type,
                                      const char* identifier,
                                      const char* output_data_json,
                                      platform_event_reply_callback_t callback,
                                      void* user_data);

/**
 * @brief 上报服务调用结果
 * @param handle 客户端句柄
 * @param id 消息ID（与请求一致）
 * @param identifier 服务标识符
 * @param input_params JSON格式的输入参数
 * @param output_params JSON格式的输出参数
 * @return 操作结果
 */
platform_result_t platform_service_report(platform_client_handle_t handle,
                                          const char* id,
                                          const char* identifier,
                                          const char* input_params_json,
                                          const char* output_params_json);

/**
 * @brief 回复设备升级
 * @param handle 客户端句柄
 * @param id 消息ID（与升级指令一致）
 * @param code 结果: "success" 或 "fail"
 * @return 操作结果
 */
platform_result_t platform_update_reply(platform_client_handle_t handle,
                                        const char* id,
                                        const char* code);

/**
 * @brief 设置服务调用回调
 * @param handle 客户端句柄
 * @param callback 回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_set_service_call_callback(platform_client_handle_t handle,
                                                      platform_service_call_callback_t callback,
                                                      void* user_data);

/**
 * @brief 设置设备升级回调
 * @param handle 客户端句柄
 * @param callback 回调函数
 * @param user_data 用户数据
 * @return 操作结果
 */
platform_result_t platform_set_update_callback(platform_client_handle_t handle,
                                                platform_update_callback_t callback,
                                                void* user_data);

/**
 * @brief 上报设备应用信息
 * @param handle 客户端句柄
 * @param report_time 上报时间（毫秒）
 * @param app_info_json JSON格式的应用信息数据
 * @return 操作结果
 */
platform_result_t platform_app_post(platform_client_handle_t handle,
                                   int64_t report_time,
                                   const char* app_info_json);

/**
 * @brief 生成消息ID（UUID格式，简化版）
 * @param id_buffer 输出缓冲区
 * @param buffer_size 缓冲区大小
 * @return 操作结果
 */
platform_result_t platform_generate_id(char* id_buffer, size_t buffer_size);

#ifdef __cplusplus
}
#endif

#endif /* PLATFORM_CLIENT_H */
